繼 Day 20 ,我們學會了如何透過 path()
來動態的產生更多的網址
但在實作上,我們知道網路位址為只在哪,但是使用者並不曉得!
因此我們可以在前端網頁加上超連結,讓使用這可以透過連結到其他頁面
這裡先示範 hard code 的寫法
# vendor template 底下的 detail.html
{% extends "base.html" %}
{% block title %} My store {% endblock %}
{% block content%}
{% for vlist in vendor_list %}
<h1> 店家 : {{vlist.vendor_name}} </h1>
<p> <a href="/vendor/{{vlist.id}}"> More detail...</a> </p>
{% endfor %}
{% endblock %}
# 對應 views 的 showtemplate
def showtemplate(request):
vendor_list = Vendor.objects.all()
context = {'vendor_list': vendor_list}
# print(vendor_list)
return render(request, 'vendors/detail.html', context)
另一種方法則是,我們都知道 vlist 參數是一個物件,也就是透過 Model - Vendor
所創建出來的,因此我們能在該 Model 下創建一個函式,也就是說
class Vendor(models.Model):
vendor_name = models.CharField(max_length = 20) # 攤販的名稱
store_name = models.CharField(max_length = 10) # 攤販店家的名稱
phone_number = models.CharField(max_length = 20) # 攤販的電話號碼
address = models.CharField(max_length = 100) # 攤販的地址
# 新增
def get_absolute_url(self):
return f"/vendor/{self.id}/"
# 並將 detail.html 修改如下
{% extends "base.html" %}
{% block title %} My store {% endblock %}
{% block content%}
{% for vlist in vendor_list %}
<h1> 店家 : {{vlist.vendor_name}} </h1>
<p> <a href= {{ vlist.get_absolute_url }}> More detail...</a> </p>
{% endfor %}
{% endblock %}
之後下 python manage.py runserver
,上面這兩種方法,你都能夠看到這樣的頁面
雖然這樣能夠成功完成我們要的功能,不過千萬不要這麼做!! 這會讓你之後維護到 咪咪帽帽
因此,今天要告訴大家的方法是,大家如果還有印象,我們撰寫 urlspatterns 時,會有一個 name 的欄位
# 回顧 urls.py
urlpatterns = [
path('', views.showtemplate),
path('<int:id>/', views.singleVendor, name='vendor_id'), # 這一行
path('create', views.vendor_create_view),
path('fcreate', views.food_create_view),
]
這一個 name 的概念就是,為這一個 path 命名,也就是說以後在別的地方使用這一個名稱 vendor_id
,再將其反轉換 reverse()
,便能夠方便的讓我們命名以及維護一個網址
那我們要如何操作呢?
讓我們延用剛剛定義的 get_absolute_url
吧!
from django.urls import reverse # 新增
# 將 get_absolute_url 修改如下
def get_absolute_url(self):
return reverse("vendor_id", kwargs={"id": self.id})
第一個參數要擺的便是我們定義的 urls name - vendor_id
,且因為在 urlspattern 裡面有規定要吃一個 整數 id,因此後方則是要將額外的參數 (kwargs) 一起帶進這一個 reverse() 函式
urlpatterns = [
path('<int:id>/', views.singleVendor, name='vendor_id'),
...略
]
你說這樣子的寫的好處在哪,好處就是 今天需要修改網址位址,只要修改 urlspattern 即可,也就是說
# 我在 網址前方多加了 haha
urlpatterns = [
path('haha<int:id>/', views.singleVendor, name='vendor_id'),
...略
]
超連結的後方也會自動加上 haha!
因為此時此刻,我們得到網址的方法是跟著 path name 綁定,所以 只要 不動到 <int:id>
, Django 會動態的幫你處理超連結綁定的工作唷! 就再也不會因為 hard code 而苦惱拉 ^^"
我們今天談到了 path 裡面的 name 如何結合 reverse 來達到 動態網址的效果,不再因為 hard-coded 的方式而讓你苦惱,reverse 可以傳入的參數不只是 kwargs, args 也可以,這部分就留給大家去研究囉!
今天講到這,我們明天見 ^^
import this ... the zen of Python!
您好,跟著文章實作已經可以做到顯示more detail超連結的部分,但是超連結過去,會顯示TypeError at /vendor/1/這樣的錯誤訊息,請問是哪裡沒有設置好嗎? 謝謝
第一個方法我可以正常顯示及超連結過去,但是第二個我的terminal畫面會一直顯示return f"/vendor/{self.id}/" 不合法,不知道是它打錯還是我哪邊有誤(我這邊先跳過)